﻿// Behavior originally contributed by Nesox / completely reworked by Chinajade
//
// LICENSE:
// This work is licensed under the
//     Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
// also known as CC-BY-NC-SA.  To view a copy of this license, visit
//      http://creativecommons.org/licenses/by-nc-sa/3.0/
// or send a letter to
//      Creative Commons // 171 Second Street, Suite 300 // San Francisco, California, 94105, USA.
//

#region Usings
using System.Linq;

using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
#endregion


namespace Honorbuddy.QuestBehaviorCore
{
	// 11Mar2013-04:41UTC chinajade
	public class VehicleAbility
	{
		public VehicleAbility(int abilityIndex /*[1..12]*/)
		{
			Contract.Requires((1 <= abilityIndex) && (abilityIndex <= 12),
								context => "1 <= abilityIndex) && (abilityIndex <= 12)");

			AbilityIndex = abilityIndex;
			_luaCommand_UseAbility = string.Format("CastPetAction({0})", abilityIndex);
			_luaQuery_IsUsable = string.Format("return GetPetActionSlotUsable({0})", abilityIndex);
			_vehicleAbilityNameDefault = string.Format("VehicleAbility({0})", abilityIndex);

			QBCLog.DeveloperInfo("NEW VehicleAbility{0}: {1}", AbilityIndex, Name);
			LogAbilityUse = true;

			AbilityUseCount = 0;
		}

		public int AbilityIndex { get; private set; }
		public int AbilityUseCount { get; private set; }
		public bool LogAbilityUse { get; set; }

		#region Private and Convenience variables
		private LocalPlayer Me { get { return QuestBehaviorBase.Me; } }

		private readonly string _luaQuery_IsUsable;
		private readonly string _luaCommand_UseAbility;
		private WoWPetSpell _vehicleAbility;
		private string _vehicleAbilityName;
		private readonly string _vehicleAbilityNameDefault;
		private readonly static WoWPetSpell.PetSpellType[] _vehicleAbilityTypes =
			{
				WoWPetSpell.PetSpellType.Action,
				WoWPetSpell.PetSpellType.Spell,
				WoWPetSpell.PetSpellType.Stance
			};
		#endregion


		// 11Mar2013-04:41UTC chinajade
		protected WoWPetSpell FindVehicleAbility()
		{
			if (!Query.IsVehicleActionBarShowing())
			{
				// assignment intentional, we want it to become null again when we exit vehicle...
				return _vehicleAbility = null;
			}

			return
				_vehicleAbility
				?? (_vehicleAbility =
						Me.PetSpells
						.FirstOrDefault(petSpell => _vehicleAbilityTypes.Contains(petSpell.SpellType)
														&& ((petSpell.ActionBarIndex + 1) == AbilityIndex)));
		}


		// 11Mar2013-04:41UTC chinajade
		protected WoWSpell FindVehicleAbilitySpell()
		{
			var vehicleAbility = FindVehicleAbility();

			return
				(vehicleAbility == null)
				? null
				: vehicleAbility.Spell;
		}


		// 11Mar2013-04:41UTC chinajade
		public bool IsAbilityReady()
		{
			var spell = FindVehicleAbilitySpell();

			return
				IsAbilityUsable()
				&& (spell != null)
				&& !spell.Cooldown;
		}


		// 11Mar2013-04:41UTC chinajade
		public bool IsAbilityUsable()
		{
			return Query.IsVehicleActionBarShowing()
				&& Lua.GetReturnVal<bool>(_luaQuery_IsUsable, 0);
		}


		public double MaxRange
		{
			get
			{
				var vehicleAbility = FindVehicleAbility();

				return (vehicleAbility != null)
					? vehicleAbility.Spell.MaxRange
					: double.NaN;
			}
		}


		// 11Mar2013-04:41UTC chinajade
		public string Name
		{
			get
			{
				var vehicleAbility = FindVehicleAbility();

				if (vehicleAbility == null)
				{
					// We want dynamic name to return to null when we exit vehicle...
					_vehicleAbilityName = null;
					return _vehicleAbilityNameDefault;
				}

				// If we don't yet know the name, acquire it...
				if (string.IsNullOrEmpty(_vehicleAbilityName))
					{ _vehicleAbilityName = string.Format("{0}({1})", vehicleAbility.ToString(), vehicleAbility.Spell.Id); }

				return _vehicleAbilityName;
			}
		}


		public bool UseAbility()
		{
			if (!Query.IsVehicleActionBarShowing())
			{
				QBCLog.Warning("Attempted to use {0} while not in Vehicle!", Name);
				return false;
			}

			if (IsAbilityReady())
			{
				Lua.DoString(_luaCommand_UseAbility);
				++AbilityUseCount;

				if (LogAbilityUse)
					{ QBCLog.DeveloperInfo("{0} ability used (count: {1})", Name, AbilityUseCount);  }

				return true;
			}

			return false;
		}
	}
}
